package org.example.supplychain.mapper;

import org.apache.ibatis.annotations.*;
import org.example.supplychain.domain.Order;
import org.example.supplychain.domain.TotalMaterial;

import java.util.List;
import java.util.Map;

@Mapper
public interface OrderMapper {

    /**
     * 添加订单
     *
     * @param order 订单
     */
    @Insert("INSERT INTO `order`(material_name,material_number,price,inventory_name,status,startTime,deadline,supplier_name,buyer_name,average_unit_price) VALUES (#{materialName},#{materialNumber},#{price},#{inventoryName},#{status},#{startTime},#{deadline},#{supplierName},#{buyerName},#{averageUnitPrice})")
    void addOrder(Order order);

    /**
     * 删除订单
     *
     * @param orderId 订单id
     */
    @Delete("DELETE FROM `order` WHERE order_id=#{orderId}")
    void deleteOrderByOrderId(long orderId);

    /**
     * 更新订单
     *
     * @param order 订单
     */
    @Update("UPDATE `order` SET material_number=#{materialNumber},price=#{price},inventory_name=#{inventoryName},status=#{status},endTime=#{endTime},deadline=#{deadline},supplier_name=#{supplierName},buyer_name=#{buyerName},average_unit_price=#{averageUnitPrice} where order_id=#{orderId}")
    void updateOrderByOrderId(Order order);

    /**
     * 更新订单材料数量
     *
     * @param order 订单
     */
    @Update("UPDATE `order` SET material_number=#{materialNumber} where order_id=#{orderId}")
    void updateOrderMaterialNumberByOrderId(Order order);

    /**
     * 更新订单价格
     *
     * @param order 订单
     */
    @Update("UPDATE `order` SET price=#{price} where order_id=#{orderId}")
    void updateOrderPriceByOrderId(Order order);

    /**
     * 更新订单状态
     *
     * @param order 订单
     */
    @Update("UPDATE `order` SET status=#{status} where order_id=#{orderId}")
    void updateOrderStatusByOrderId(Order order);

    /**
     * 更新订单结束时间
     *
     * @param order 订单
     */
    @Update("UPDATE `order` SET endTime=#{endTime} where order_id=#{orderId}")
    void updateOrderEndTimeByOrderId(Order order);

    /**
     * 更新订单截止时间
     *
     * @param order 订单
     */
    @Update("UPDATE `order` SET deadline=#{deadline} where order_id=#{orderId}")
    void updateOrderDeadlineByOrderId(Order order);

    /**
     * 更新订单供应商
     *
     * @param order 订单
     */
    @Update("UPDATE `order` SET supplier_name=#{supplierName} where order_id=#{orderId}")
    void updateOrderSupplierNameByOrderId(Order order);

    /**
     * 更新订单买家
     *
     * @param order 订单
     */
    @Update("UPDATE `order` SET buyer_name=#{buyerName} where order_id=#{orderId}")
    void updateOrderBuyerNameByOrderId(Order order);

    /**
     * 更新订单平均单价
     *
     * @param order 订单
     */
    @Update("UPDATE `order` SET average_unit_price=#{averageUnitPrice} where order_id=#{orderId}")
    void updateOrderAverageUnitPriceByOrderId(Order order);


    @Select("SELECT * FROM `order` WHERE order_id=#{orderId}")
    Order getOrderByOrderId(long orderId);

    /**
     * 根据订单材料名与订单开始时间查询订单
     *
     * @return 订单
     */
    @Select("SELECT * FROM `order`")
    List<Order> getAllOrders();

    /**
     * 展示最近一周内将要到达截止日期的订单清单，按截止日期升序排列。（日期最紧迫的放在最上面）
     *
     * @return 订单列表
     */
    @Select("SELECT * FROM `order` WHERE deadline BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 7 DAY) ORDER BY deadline ASC")
    List<Order> getOrdersNearDeadline();

    /**
     * 展示原料总量已小于警戒值的所有原料
     *
     * @return 原料管理列表
     */
    @Select("SELECT * FROM total_material WHERE warning_state=TRUE")
    List<TotalMaterial> getWarningMaterial();

    /**
     * 供应商管理
     *
     * @return 供应商管理列表
     */
    @Select("SELECT supplier.supplier_name AS supplier_name,  material.material_name AS material_name, material.average_unit_price AS average_unit_price,supplier.mark AS mark, supplier.place AS place, supplier.phone AS phone FROM supplier LEFT JOIN material ON supplier.supplier_name = material.supplier_name")
    List<Map<String, Object>> supplierManagement();

    /**
     * 获取订单中的所有原料名
     * @return 原料名列表
     */
    @Select("SELECT DISTINCT material_name FROM `order`")
    List<String> getAllMaterialName();
}
